﻿using System.Collections.Generic;
using Microsoft.VisualStudio.Debugger.Interop;
using Red.Scripts.Debugger.Defines;

namespace Red.Scripts.Debugger.Remote
{
    internal class Enumeration<T> where T : class
    {
        protected int _position;

        public List<T> Elements { get; protected set; } = new List<T>();

        public Enumeration()
        {
            Elements = new List<T>();
        }

        protected Enumeration( int position, List<T> elements )
        {
            _position = position;
            Elements = new List<T>( elements );
        }

        public int GetCount( out uint pcelt )
        {
            pcelt = (uint)Elements.Count;

            return Constants.S_OK;
        }

        public int Next( uint celt, T[] rgelt, ref uint pceltFetched )
        {
            List<T> range = Elements.GetRange( _position, (int)celt );
            range.CopyTo( rgelt );
            pceltFetched = (uint)range.Count;

            return Skip( celt );
        }

        public int Reset()
        {
            _position = 0;

            return Constants.S_OK;
        }

        public int Skip( uint celt )
        {
            _position += (int)celt;

            if( _position > Elements.Count )
            {
                _position = Elements.Count;
                return Constants.S_FALSE;
            }

            return Constants.S_OK;
        }
    }

    internal class EnumeratedProcesses : Enumeration<IDebugProcess2>, IEnumDebugProcesses2
    {
        public EnumeratedProcesses() : base()
        {

        }

        public EnumeratedProcesses( int position, List<IDebugProcess2> elements ) : base( position, elements )
        {

        }

        public int Clone( out IEnumDebugProcesses2 ppEnum )
        {
            ppEnum = new EnumeratedProcesses( _position, Elements );

            return Constants.S_OK;
        }
    }

    internal class EnumeratedPrograms : Enumeration<IDebugProgram2>, IEnumDebugPrograms2
    {
        public EnumeratedPrograms() : base()
        {

        }

        public EnumeratedPrograms( int position, List<IDebugProgram2> elements ) : base( position, elements )
        {

        }

        public int Clone( out IEnumDebugPrograms2 ppEnum )
        {
            ppEnum = new EnumeratedPrograms( _position, Elements );

            return Constants.S_OK;
        }
    }
}
